package roborally;

import be.kuleuven.cs.som.annotate.*;
import Exceptions.IllegalCoordinateException;

/**
 * @author Jef Keijers/Bachelor of Science: Informatics
 * @version 1.0
 */
@Value
public class Position {

	public Position(long x, long y, Board board) throws IllegalCoordinateException {
		if (board==null)
			throw new IllegalCoordinateException();
		setX(x,board);
		setY(y,board);			
	}

	public long getX() 
	{
		return this.x;
	}

	public long getY()
	{
		return this.y;
	}

	public void setX(long x,Board board) throws IllegalCoordinateException
	{
		if(canHaveAsXCoordinate(x,board))
			this.x = x;
		else throw new IllegalCoordinateException();
	}

	public void setY(long y,Board board) throws IllegalCoordinateException
	{
		if(canHaveAsYCoordinate(y,board))
			this.y = y;
		else throw new IllegalCoordinateException();
	}
	

	private long x;

	private long y;
	
	public boolean canHaveAsXCoordinate(long x, Board board){
		if ((x < board.getWidth()) && (x>=0)){
			return true;
		} else return false;
	}

	public boolean canHaveAsYCoordinate(long y, Board board){
		if ((y < board.getHeight()) && (y>=0)){
			return true;
		} else return false;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (int) (x ^ (x >>> 32));
		result = prime * result + (int) (y ^ (y >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Position other = (Position) obj;
		if (x != other.x)
			return false;
		if (y != other.y)
			return false;
		return true;
	}
	
	public String toString() {
		return String.format("(%d, %d)", this.getX(), this.getY());
	}

	public Position copy(Board board) throws IllegalCoordinateException {
		return new Position(this.getX(),this.getY(),board);
	}

	public Direction getDirectionTo(Position position) {
		long XDifference=position.getX()-this.getX();
		long YDifference=position.getY()-this.getY();
		
		if (XDifference>0) 
			return Direction.RIGHT;
		else if (XDifference<0) 
			return Direction.LEFT;
		else if (YDifference > 0)
			return Direction.DOWN;
		else if (YDifference < 0)
			return Direction.UP;
		return null;
		
	}
	
	public Position move(Direction dir,Board board) throws IllegalCoordinateException {
		Position copy=this.copy(board);
		switch (dir) {
		
		case UP:
				copy.setY(getY()-1,board);
				break;
		case DOWN:
				copy.setY(getY()+1,board);
				break;
		case RIGHT:
				copy.setX(getX()+1,board);
				break;
		case LEFT:
				copy.setX(getX()-1,board);
				break;
		}
		
		return copy;
	}

}
